function results = make_returns_288(file_name,start_date,finish_date,winsorizing,alpha,replace_option)

% ---------------------------------------------------------------------------------- %

% This functions creates returns sampled at a 5 minute frequency.
% The final price of day t-1 (at 17:59:59.99999999) is used to compute the first
% return on day t at 18:04:59.9999999999. Thus, there is 288 return
% obersavations per trading day (except the very first trading day where
% there is 287)

% INPUTS: (1) filename tells you what type of interpolation scheme we are
% using. (2) start date and end date for making log price matrices

% ----------- Choose Winsorizing --------------------------------------------------- %
% winsorizing - no = 0, yes = 1
% alpha - the winsorization level. Eg, a 0.9 = 90% winsorization would see all data below the 5th percentile set to the 5th percentile, and data above the 95th percentile set to the 95th percentile.
% replace_option = 0: extreme observations are replaced with NaNs.
% replace_option = 1: extreme observations are replaced with the lower/upper quantiles/percentiles

% ---------------------------------------------------------------------------------- %

% Load data and work out if its trade or quotes and compute log prices

data = load(file_name);

if strcmp(file_name,'../01_data/es_trades_5minute_EST') == 1 
    caldt               = data.caldt_daily;
    caldt_mat           = data.caldt_mat;
    price               = data.price_VWAP_mat;
    log_price           = log(price);
elseif strcmp(file_name,'../01_data/es_quotes_5minute_EST') == 1 
    caldt               = data.caldt_daily;
    caldt_mat           = data.caldt_mat;
    price               = data.MID_mat;
    log_price           = log(price);
end

% choose sample period
beg                 = find_closest(caldt,start_date);
fin                 = find_closest(caldt,finish_date);

caldt               = caldt(beg:fin);
T                   = length(caldt);
caldt_mat           = caldt_mat(beg:fin,:);
log_price           = log_price(beg:fin,:);
price               = price(beg:fin,:);

% Fill in last price of the day as first price the following day
log_price_temp              = nan(size(log_price,1), size(log_price,2)+1);
log_price_temp(1:end,2:end) = log_price;
log_price_temp(1,1)         = log_price_temp(1,2);
log_price_temp(2:end,1)     = log_price_temp(1:end-1,end);
log_price                   = log_price_temp;

% Fill in last price of the day as first price the following day
price_temp                  = nan(size(price,1), size(price,2)+1);
price_temp(1:end,2:end)     = price;
price_temp(1,1)             = price_temp(1,2);
price_temp(2:end,1)         = price_temp(1:end-1,end);
price                       = price_temp;


% ---------------------------------------------------------------------------------- %

% VOLUME AND PRICE indices run from 1:288 which is 18:05 - 18:00 NY time
% RETURNS are one interval shorter running from 1:287 which is 18:10 - 18:00 NY time

ADIndex = 1 : 288;              % 18:05 - 18:00
ONIndex = 1 : 186;              % 18:10 - 9:30
IDIndex = 187 : 267;            % 9:35 - 16:15

ASIndex          = 1:96      ;                % 18:05 - 02:00 Asian markets open (approx)
EUIndex          = 109:186   ;                % 03:05 - 09:30 European markets open (approx)
LOIndex1         = 84:95     ;                % 00:05 - 01:00 Pre Pre London open
LOIndex2         = 85:96     ;                % 01:05 - 02:00 Pre London open
LOIndex          = 97:108    ;                % 02:05 - 03:00 London open
ODPlusIndex      = 85:120    ;                % 01:05 - 04:00 Long overnight drift
ORIndex          = 175:192   ;                % 08:35 - 10:00 Opening reversal

% ---------------------------------------------------------------------------------- %

% winsorize or not

if winsorizing == 0
    log_returns = diff(log_price,1,2);
    returns = exp(log_returns)-1;
elseif winsorizing == 1
    log_returns = diff(log_price,1,2);
    log_returns_temp = log_returns;
    returns_temp = exp(log_returns)-1;
    log_returns = WinsorizeData(log_returns , alpha, replace_option);
    returns = exp(log_returns)-1;
end

% ---------------------------------------------------------------------------------- %
% Log returns

% overnight versus intraday log returns annualized (5 by 5 minutes) - cross-sectional
log_return_AD  = log_returns(:,ADIndex) ;
log_return_ON  = log_returns(:,ONIndex) ;
log_return_ID  = log_returns(:,IDIndex) ;
log_return_AS  = log_returns(:,ASIndex) ;
log_return_EU  = log_returns(:,EUIndex) ;
log_return_LO1 = log_returns(:,LOIndex1);
log_return_LO2 = log_returns(:,LOIndex2);
log_return_LO  = log_returns(:,LOIndex) ;
log_return_OR  = log_returns(:,ORIndex) ;

% 15 minute log returns
indx = [3 : 3 : length(log_returns(1,:))];
indx_loop = [0 , indx];
log_return_15b15_AD = nan(size(log_returns,1),24*4);

for H = 1 : round(length(log_returns(1,:))/12*4)
    log_return_15b15_AD(:,H) = sum(log_returns(:,indx_loop(H)+1 : indx_loop(H+1)),2);
end

% hour by hour log returns
indx = [12 : 12 : length(log_returns(1,:))];
indx_loop = [0 , indx];
log_return_HbH_AD = nan(size(log_returns,1),24);

for H = 1 : round(length(log_returns(1,:))/12)
    log_return_HbH_AD(:,H) = sum(log_returns(:,indx_loop(H)+1 : indx_loop(H+1)),2);
end

% SUMMATION OVER DAYS
log_return_DbD_AD        = nansum(log_returns(:,ADIndex),2);
log_return_DbD_ON        = nansum(log_returns(:,ONIndex),2);
log_return_DbD_ID        = nansum(log_returns(:,IDIndex),2);
log_return_DbD_AS        = nansum(log_returns(:,ASIndex),2);
log_return_DbD_EU        = nansum(log_returns(:,EUIndex),2);
log_return_DbD_LO1       = nansum(log_returns(:,LOIndex1),2);
log_return_DbD_LO2       = nansum(log_returns(:,LOIndex2),2);
log_return_DbD_LO        = nansum(log_returns(:,LOIndex),2);
log_return_DbD_ODPlus    = nansum(log_returns(:,ODPlusIndex),2);
log_return_DbD_ORShort   = -1*nansum(log_returns(:,ORIndex),2);
log_return_DbD_OR        = nansum(log_returns(:,ORIndex),2);

% cumulative 5 minute log returns
cum_log_returns         = cumsum(log_returns(:,ADIndex),2,'omitnan');

% ---------------------------------------------------------------------------------- %
% Simple Returns

% overnight versus intraday returns annualized (5 by 5 minutes) - cross-sectional
return_AD = returns(:,ADIndex);
return_ON = returns(:,ONIndex);
return_ID = returns(:,IDIndex);
return_AS = returns(:,ASIndex);
return_EU = returns(:,EUIndex);
return_LO1 = returns(:,LOIndex1);
return_LO2 = returns(:,LOIndex2);
return_LO = returns(:,LOIndex);
return_OR = returns(:,LOIndex);

% 15 by 15 returns
return_15b15_AD = exp(log_return_15b15_AD)-1;

% hour by hour returns
return_HbH_AD = exp(log_return_HbH_AD)-1;

%  OVER DAYS
return_DbD_AD       = exp(log_return_DbD_AD)-1;
return_DbD_ON       = exp(log_return_DbD_ON)-1;
return_DbD_ID       = exp(log_return_DbD_ID)-1;
return_DbD_AS       = exp(log_return_DbD_AS)-1;
return_DbD_EU       = exp(log_return_DbD_EU)-1;
return_DbD_LO1      = exp(log_return_DbD_LO1)-1;
return_DbD_LO2      = exp(log_return_DbD_LO2)-1;
return_DbD_LO       = exp(log_return_DbD_LO)-1;
return_DbD_ODPlus   = exp(log_return_DbD_ODPlus)-1;
return_DbD_ORShort  = exp(log_return_DbD_ORShort)-1;
return_DbD_OR       = exp(log_return_DbD_OR)-1;

% cumulative 5 minute returns - CROSS-SECTIONAL
gross_returns = 1+return_AD;
cum_returns = cumprod(gross_returns,2);

% ---------------------------------------------------------------------------------- %
% TIME SERIES OF THE ON vs ID vs AD CUMULATIVE RETURN

% cumulative product of simple returns over all days
cum_returns_AD      = cumprod(1+return_DbD_AD);
cum_returns_ON      = cumprod(1+return_DbD_ON);
cum_returns_ID      = cumprod(1+return_DbD_ID);
cum_returns_AS      = cumprod(1+return_DbD_AS);
cum_returns_EU      = cumprod(1+return_DbD_EU);
cum_returns_LO1     = cumprod(1+return_DbD_LO2);
cum_returns_LO2     = cumprod(1+return_DbD_LO2);
cum_returns_LO      = cumprod(1+return_DbD_LO);
cum_returns_ODPlus  = cumprod(1+return_DbD_ODPlus);
cum_returns_ORShort = cumprod(1+return_DbD_ORShort);
cum_returns_OR      = cumprod(1+return_DbD_OR);

%normalize
cum_returns_AD           = cum_returns_AD./cum_returns_AD(1);
cum_returns_ON           = cum_returns_ON./cum_returns_ON(1);
cum_returns_ID           = cum_returns_ID./cum_returns_ID(1);
cum_returns_AS           = cum_returns_AS./cum_returns_AS(1);
cum_returns_EU           = cum_returns_EU./cum_returns_EU(1);
cum_returns_LO1          = cum_returns_LO1./cum_returns_LO1(1);
cum_returns_LO2          = cum_returns_LO2./cum_returns_LO2(1);
cum_returns_LO           = cum_returns_LO./cum_returns_LO(1);
cum_returns_ODPlus       = cum_returns_ODPlus./cum_returns_ODPlus(1);
cum_returns_ORShort      = cum_returns_ORShort./cum_returns_ORShort(1);
cum_returns_OR           = cum_returns_OR./cum_returns_OR(1);

%-----------------------------------------------------------------------------------%

% save everything in a structure

results.caldt                       = caldt;
results.caldt_mat                   = caldt_mat;
results.price                       = price;
results.log_price                   = log_price;
results.T                           = T;
results.log_returns                 = log_returns;
results.returns                     = returns;
results.log_return_AD               = log_return_AD;
results.log_return_ON               = log_return_ON;
results.log_return_ID               = log_return_ID;
results.log_return_AS               = log_return_AS;
results.log_return_EU               = log_return_EU;
results.log_return_LO1              = log_return_LO1;
results.log_return_LO2              = log_return_LO2;
results.log_return_LO               = log_return_LO;
results.log_return_OR               = log_return_OR;
results.log_return_15b15_AD         = log_return_15b15_AD;
results.log_return_HbH_AD           = log_return_HbH_AD;
results.log_return_DbD_AD           = log_return_DbD_AD;
results.log_return_DbD_ON           = log_return_DbD_ON;
results.log_return_DbD_ID           = log_return_DbD_ID;
results.log_return_DbD_AS           = log_return_DbD_AS;
results.log_return_DbD_EU           = log_return_DbD_EU;
results.log_return_DbD_LO1          = log_return_DbD_LO1;
results.log_return_DbD_LO2          = log_return_DbD_LO2;
results.log_return_DbD_LO           = log_return_DbD_LO;
results.log_return_DbD_OR           = log_return_DbD_OR;
results.log_return_DbD_ODPlus       = log_return_DbD_ODPlus;
results.log_return_DbD_ORShort      = log_return_DbD_ORShort;
results.log_return_DbD_OR           = log_return_DbD_OR;
results.cum_log_returns             = cum_log_returns;
results.return_AD                   = return_AD;
results.return_ON                   = return_ON;
results.return_ID                   = return_ID;
results.return_AS                   = return_AS;
results.return_EU                   = return_EU;
results.return_LO                   = return_LO;
results.return_LO1                  = return_LO1;
results.return_LO2                  = return_LO2;
results.return_OR                   = return_OR;
results.return_15b15_AD             = return_15b15_AD;
results.return_HbH_AD               = return_HbH_AD;
results.return_DbD_AD               = return_DbD_AD;
results.return_DbD_ON               = return_DbD_ON;
results.return_DbD_ID               = return_DbD_ID;
results.return_DbD_AS               = return_DbD_AS;
results.return_DbD_EU               = return_DbD_EU;
results.return_DbD_LO1              = return_DbD_LO1;
results.return_DbD_LO2              = return_DbD_LO2;
results.return_DbD_LO               = return_DbD_LO;
results.return_DbD_OR               = return_DbD_OR;
results.cum_returns                 = cum_returns;
results.cum_returns_AD              = cum_returns_AD;
results.cum_returns_ON              = cum_returns_ON;
results.cum_returns_ID              = cum_returns_ID;
results.cum_returns_AS              = cum_returns_AS;
results.cum_returns_EU              = cum_returns_EU;
results.cum_returns_LO1             = cum_returns_LO1;
results.cum_returns_LO2             = cum_returns_LO2;
results.cum_returns_LO              = cum_returns_LO;
results.cum_returns_ODPlus          = cum_returns_ODPlus;
results.cum_returns_ORShort         = cum_returns_ORShort;
results.cum_returns_OR              = cum_returns_OR;

return;
